#ifndef MGAPP_H
#define MGAPP_H

#include <QObject>
#include <QTimer>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QTcpSocket>
#include <QUdpSocket>
#include <QHostAddress>
#include <QSettings>
#include <time.h>


class SerialManage : public QObject {
    Q_OBJECT
private:

    static SerialManage *instance;

    SerialManage();

    ~SerialManage() override;

    QTimer timer;

public:

    QList<QString> serials;

    static SerialManage *getInstance();

private slots:

    void onUpdateList();

signals:

    void listChanged(QList<QString> &serials);
};

class MGApp : public QObject
{
    Q_OBJECT
private:
    QSerialPort serial;
    QTcpSocket tcpSocket;
    QUdpSocket udpSocket;
    std::chrono::system_clock::time_point startTime;
    std::chrono::system_clock::time_point endTime;
    QSettings *config = nullptr;
public:
    explicit MGApp(QObject *parent = nullptr);

    ~MGApp();

    int protocol = 0; //0:RTU 1:TCP 2:UDP
    QStringList serialList;
    QString device = "关闭";
    int baud = 115200;
    int parity = 0;
    int dataBit = 8;
    int stopBit = 1;
    bool linkStatus = false;
    long long responseTime = 0;
    QString ip = "127.0.0.1";
    quint64 port = 502;
    quint16 mbapId = 0;

    quint32 sendframeNum = 0;
    quint32 recvframeNum = 0;
    quint64 sendByteNum = 0;
    quint64 recvByteNum = 0;

    Q_INVOKABLE void openSerial();

    Q_INVOKABLE void closeSerial();

    Q_INVOKABLE QString sendData(int code, QString slaveStr, QString regStr, QString lenStr, QString varStr, QString regStr2 = "");

    Q_INVOKABLE QString toUpper(const QString &str);

private slots:
    void onBaudChanged();

    void onParityChanged();

    void onDataBitChanged();

    void onStopBitChanged();

    void onReadyRead();

signals:
    void deviceChanged();

    void baudChanged();

    void parityChanged();

    void dataBitChanged();

    void stopBitChanged();

    void serialListChanged();

    void linkStatusChanged();

    void responseTimeChanged();

    void sendDataChanged(const QString &str);

    void recvDataChanged(const QString &str);

    void recvData(int code, QString valStr);
    void sendframeNumChanged();
    void recvframeNumChanged();
    void sendByteNumChanged();
    void recvByteNumChanged();
    void protocolChanged();
    void ipChanged();
    void portChanged();
    void mbapIdChanged();

private:
    Q_PROPERTY(QStringList serialList MEMBER serialList NOTIFY serialListChanged)
    Q_PROPERTY(QString device MEMBER device NOTIFY deviceChanged)
    Q_PROPERTY(int baud MEMBER baud NOTIFY baudChanged)
    Q_PROPERTY(int parity MEMBER parity NOTIFY parityChanged)
    Q_PROPERTY(int dataBit MEMBER dataBit NOTIFY dataBitChanged)
    Q_PROPERTY(int stopBit MEMBER stopBit NOTIFY stopBitChanged)
    Q_PROPERTY(bool linkStatus MEMBER linkStatus NOTIFY linkStatusChanged)
    Q_PROPERTY(long long responseTime MEMBER responseTime NOTIFY responseTimeChanged)
    Q_PROPERTY(quint32 sendframeNum MEMBER sendframeNum NOTIFY sendframeNumChanged)
    Q_PROPERTY(quint32 recvframeNum MEMBER recvframeNum NOTIFY recvframeNumChanged)
    Q_PROPERTY(quint64 sendByteNum MEMBER sendByteNum NOTIFY sendByteNumChanged)
    Q_PROPERTY(quint64 recvByteNum MEMBER recvByteNum NOTIFY recvByteNumChanged)
    Q_PROPERTY(int protocol MEMBER protocol NOTIFY protocolChanged)
    Q_PROPERTY(QString ip MEMBER ip NOTIFY ipChanged)
    Q_PROPERTY(quint64 port MEMBER port NOTIFY portChanged)
    Q_PROPERTY(quint16 mbapId MEMBER mbapId NOTIFY mbapIdChanged)
};

#endif // MGAPP_H
